package com.nantong.admin.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import com.nantong.admin.domain.Quote;
import com.nantong.admin.domain.QuoteItem;
import com.nantong.admin.domain.SysUser;
import com.nantong.admin.domain.model.request.quote.QuoteCreateRequest;
import com.nantong.admin.domain.model.request.quote.QuoteItemRequest;
import com.nantong.admin.domain.model.request.quote.QuoteSearch;
import com.nantong.admin.domain.model.response.quote.QuoteVo;
import com.nantong.admin.mapper.QuoteItemMapper;
import com.nantong.admin.mapper.QuoteMapper;
import com.nantong.admin.mapper.SysUserMapper;
import com.nantong.admin.service.IProductService;
import com.nantong.admin.service.IQuoteService;
import com.nantong.admin.util.LoginHelper;
import com.nantong.common.core.exception.ServiceException;
import com.nantong.common.core.utils.StringUtils;
import com.nantong.common.mybatis.core.page.PageQuery;
import com.nantong.common.mybatis.core.page.TableDataInfo;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 报价单Service实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QuoteServiceImpl extends ServiceImpl<QuoteMapper, Quote> implements IQuoteService {

    private final QuoteMapper quoteMapper;
    private final QuoteItemMapper quoteItemMapper;
    private final SysUserMapper userMapper;
    private final IProductService productService;

    @Override
    public TableDataInfo<QuoteVo> selectPageList(QuoteSearch quoteSearch, PageQuery pageQuery) {
        Page<QuoteVo> page = quoteMapper.selectPageList(pageQuery.build(), buildQueryWrapper(quoteSearch));
        // 填充状态描述
        if (page.getRecords() != null) {
            page.getRecords().forEach(vo -> {
                vo.setStatusDesc(getStatusDesc(vo.getStatus()));
                Long customerId = vo.getCustomerId();
                if (customerId != null) {
                    SysUser customer = userMapper.selectById(customerId);
                    if (customer != null) {
                        vo.setCustomerName(customer.getNickName());
                    }
                }
            });
        }
        return TableDataInfo.build(page);
    }

    @Override
    public List<QuoteVo> searchList(QuoteSearch quoteSearch) {
        Wrapper<Quote> quoteWrapper = this.buildQueryWrapper(quoteSearch);
        List<QuoteVo> quoteVoList = quoteMapper.selectQuoteList(quoteWrapper);

        // 为每个报价单设置状态描述
        if (quoteVoList != null) {
            quoteVoList.forEach(quoteVo -> {
                quoteVo.setStatusDesc(getStatusDesc(quoteVo.getStatus()));
                Long customerId = quoteVo.getCustomerId();
                if (customerId != null) {
                    SysUser customer = userMapper.selectById(customerId);
                    if (customer != null) {
                        quoteVo.setCustomerName(customer.getNickName());
                    }
                }
            });
        }

        return quoteVoList;
    }

    @Override
    public QuoteVo selectQuoteById(Long quoteId) {
        QuoteVo quoteVo = quoteMapper.selectQuoteDetail(quoteId);
        if (quoteVo != null) {
            quoteVo.setStatusDesc(getStatusDesc(quoteVo.getStatus()));
        }
        return quoteVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertQuote(QuoteCreateRequest quoteCreateRequest) {
        // 生成报价单号
        String quoteNo = generateQuoteNo();

        // 创建报价单主表
        Quote quote = new Quote();
        BeanUtils.copyProperties(quoteCreateRequest, quote);
        quote.setQuoteNo(quoteNo);
        quote.setStatus(1); // 默认状态为草稿

        // 自动填充销售人员信息
        fillSalesPersonInfo(quote);

        // 计算总金额和最终金额
        calculateQuoteAmount(quote, quoteCreateRequest.getItems());

        if (!this.save(quote)) {
            throw new ServiceException("创建报价单失败");
        }

        // 创建报价单明细
        saveQuoteItems(quote.getQuoteId(), quoteCreateRequest.getItems());

        return 1;
    }

    /**
     * 填充销售人员信息
     */
    private void fillSalesPersonInfo(Quote quote) {
        try {
            // 获取当前登录用户
            var loginUser = LoginHelper.getLoginUser();
            if (loginUser != null) {
                // 设置报价人ID（当前登录用户ID）
                quote.setSalerId(loginUser.getUserId());
                // 通过用户ID获取用户详情
                SysUser user = userMapper.selectById(loginUser.getUserId());
                if (user != null) {
                    // 设置销售人员姓名（用户昵称优先）
                    String salesPersonName = StringUtils.isNotBlank(user.getNickName())
                            ? user.getNickName()
                            : user.getUserName();
                    quote.setSalesPerson(salesPersonName);

                    // 设置销售人员手机号
                    quote.setSalerPhone(user.getPhonenumber());
                } else {
                    // 如果没有找到用户详情，则使用loginUser中的用户名
                    quote.setSalesPerson(loginUser.getUsername());
                }

                // 设置默认有效期（如果未设置）
                if (quote.getValidDays() == null) {
                    quote.setValidDays(30); // 默认30天
                }
            }
        } catch (Exception e) {
            // 获取用户信息失败时记录日志，但不影响主流程
            log.error("自动填充销售人员信息失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQuote(QuoteCreateRequest quoteCreateRequest) {
        if (quoteCreateRequest.getQuoteId() == null) {
            throw new ServiceException("报价单ID不能为空");
        }

        // 更新报价单主表
        Quote quote = new Quote();
        BeanUtils.copyProperties(quoteCreateRequest, quote);

        // 如果是更新状态，不修改销售人员信息
        // 只有状态为1(草稿)时才允许修改销售人员信息
        Quote oldQuote = this.getById(quote.getQuoteId());
        if (oldQuote != null && oldQuote.getStatus() == 1) {
            // 填充销售人员信息（仅对草稿状态的报价单进行自动填充）
            fillSalesPersonInfo(quote);
        }

        // 计算总金额和最终金额
        calculateQuoteAmount(quote, quoteCreateRequest.getItems());

        if (!this.updateById(quote)) {
            throw new ServiceException("更新报价单失败");
        }

        // 删除原有明细
        quoteItemMapper.deleteItemsByQuoteId(quote.getQuoteId());

        // 创建新的明细
        saveQuoteItems(quote.getQuoteId(), quoteCreateRequest.getItems());

        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteQuoteById(Long quoteId) {
        // 删除报价单明细
        quoteItemMapper.deleteItemsByQuoteId(quoteId);

        // 删除报价单主表
        return this.removeById(quoteId) ? 1 : 0;
    }

    @Override
    public List<QuoteVo> selectQuotesByCustomerId(Long customerId) {
        return quoteMapper.selectQuotesByCustomerId(customerId);
    }

    @Override
    public String generateQuoteNo() {
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String prefix = "Q" + date;

        // 查询今天最大的报价单号
        LambdaQueryWrapper<Quote> wrapper = Wrappers.lambdaQuery();
        wrapper.likeRight(Quote::getQuoteNo, prefix)
                .orderByDesc(Quote::getQuoteNo)
                .last("LIMIT 1");

        Quote lastQuote = this.getOne(wrapper);

        int sequence = 1;
        if (lastQuote != null && StrUtil.isNotBlank(lastQuote.getQuoteNo())) {
            String lastNo = lastQuote.getQuoteNo();
            String lastSequence = lastNo.substring(prefix.length());
            try {
                sequence = Integer.parseInt(lastSequence) + 1;
            } catch (NumberFormatException e) {
                sequence = 1;
            }
        }

        return prefix + String.format("%04d", sequence);
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<Quote> buildQueryWrapper(QuoteSearch quoteSearch) {
        Map<String, Object> params = quoteSearch.getParams();
        LambdaQueryWrapper<Quote> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(quoteSearch.getSalesPerson()), Quote::getSalesPerson,
                        quoteSearch.getSalesPerson())
                .eq(quoteSearch.getCustomerId() != null, Quote::getCustomerId,
                        quoteSearch.getCustomerId())
                .eq(ObjectUtil.isNotNull(quoteSearch.getStatus()), Quote::getStatus, quoteSearch.getStatus())
                .between(params.get("beginTime") != null && params.get("endTime") != null,
                        Quote::getCreateTime, params.get("beginTime"), params.get("endTime"));

        return wrapper;
    }

    /**
     * 保存报价单明细
     */
    private void saveQuoteItems(Long quoteId, List<QuoteItemRequest> itemRequests) {
        if (itemRequests != null && !itemRequests.isEmpty()) {
            List<QuoteItem> quoteItems = itemRequests.stream()
                    .filter(item -> item != null && item.getProductId() != null && item.getQuantity() != null &&
                            item.getQuantity() > 0)
                    .map(item -> {
                        QuoteItem quoteItem = new QuoteItem();
                        quoteItem.setQuoteId(quoteId);
                        quoteItem.setProductId(item.getProductId());
                        quoteItem.setQuantity(item.getQuantity());
                        quoteItem.setRemarks(item.getRemarks());

                        // 获取产品信息
                        var product = productService.getById(item.getProductId());
                        if (product != null) {
                            quoteItem.setProductName(product.getProductName());
                            quoteItem.setUnitPrice(product.getUnitPrice());
                            quoteItem.setTotalPrice(
                                    product.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
                        }

                        return quoteItem;
                    })
                    .collect(Collectors.toList());

            if (!quoteItems.isEmpty()) {
                for (QuoteItem item : quoteItems) {
                    quoteItemMapper.insert(item);
                }
            }
        }
    }

    /**
     * 计算报价单金额
     */
    private void calculateQuoteAmount(Quote quote, List<QuoteItemRequest> items) {
        BigDecimal totalAmount = BigDecimal.ZERO;

        if (items != null && !items.isEmpty()) {
            for (QuoteItemRequest item : items) {
                if (item != null && item.getProductId() != null && item.getQuantity() != null &&
                        item.getQuantity() > 0) {
                    var product = productService.getById(item.getProductId());
                    if (product != null && product.getUnitPrice() != null) {
                        BigDecimal itemTotal = product.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity()));
                        totalAmount = totalAmount.add(itemTotal);
                    }
                }
            }
        }

        quote.setTotalAmount(totalAmount);

        // 设置优惠金额和最终金额
        BigDecimal discountAmount = quote.getDiscountAmount() != null ? quote.getDiscountAmount() : BigDecimal.ZERO;
        BigDecimal finalAmount = totalAmount.subtract(discountAmount);

        if (finalAmount.compareTo(BigDecimal.ZERO) < 0) {
            finalAmount = BigDecimal.ZERO;
        }

        quote.setFinalAmount(finalAmount);
    }

    /**
     * 获取状态描述
     */
    private String getStatusDesc(Integer status) {
        switch (status) {
            case 1:
                return "草稿";
            case 2:
                return "待审核";
            case 3:
                return "已接收";
            case 4:
                return "已拒绝";
            default:
                return "未知";
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateQuoteStatus(Long quoteId, Integer status) {
        // 只更新报价单状态，不修改报价单明细
        Quote quote = this.getById(quoteId);
        if (quote == null) {
            throw new ServiceException("报价单不存在");
        }

        quote.setStatus(status);
        return this.updateById(quote) ? 1 : 0;
    }
}